#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   App_WriteDataById_0x2E_test.py
@Time    :   2022/9/13 13:31:28
@Author  :   YangLiang
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from commDriver.modbus_plc import *
from gettext import find
from xmlrpc.client import Fault
from pytest_assume.plugin import assume

import pytest
import logging
import time
import requests
from sympy import I
# from sympy import assuming
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable

from sqlalchemy import false
import Set_up

sys.dont_write_bytecode = True

class Test_ReportSupportedDTC_phy(object):

     #物理寻址，默认模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
     def test_ReportSupportedDTC_Default_Phy(self,action,Driver):
          iStep = 1
          iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
          time.sleep(1)
          self.testReportSupportedDTC(Driver,1)
          
     #物理寻址，扩展模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in extended session with physical addressing")
     def test_ReportSupportedDTC_Extended_Phy(self,action,Driver):
          self.testReportSupportedDTC(Driver,3)





     def testReportSupportedDTC(self, Driver,session):
          time.sleep(1)
          current_failure  = [[0x00,0x00,0x00]]
          iStep = 1
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], session, iStep, False, 'UDS', 'ClearFault')
          iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)

          # 获取存在的当前故障
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], 0, iStep, False, 'UDS', 'noClearFault')
          for i in range(3,size,4):
               current_failure.append(uds_resp[i:i+3])
          historical_failure=[[0x00,0x00,0x00]]

          # 检查当前故障状态
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 设置电压为17v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 17, 1.5, iStep)
          current_failure.append([0xAC,0xCE,0x17])   #当前故障list
          historical_failure=[[0x00,0x00,0x00]]   #历史故障list
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 设置电压为8v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 8, 1.5, iStep)
          current_failure.append([0xAC,0xCF,0x16])
          current_failure.remove([0xAC,0xCE,0x17])
          historical_failure=[[0xAC,0xCE,0x17]]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)
          
          # 设置电压为12v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 12, 1.5, iStep)
          current_failure.remove([0xAC,0xCF,0x16])
          historical_failure=[[0xAC,0xCF,0x16],[0xAC,0xCE,0x17]]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)
          time.sleep(1)
          # 重启产品后，检查故障状态
          iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], session, iStep, False, 'UDS', 'noClearFault')
          historical_failure=[0x00,0x00,0x00] #[[0xAC,0xCF,0x16],[0xAC,0xCE,0x17]]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 清除故障后，检查故障状态
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x14,0xFF,0xFF,0xFF], [0x54], 0, iStep, False, 'UDS', 'noClearFault')
          time.sleep(2)
          historical_failure=[0x00,0x00,0x00]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)



     def checkFailureStatus(self,Driver,uds_resp,current_failure,historical_failure,iStep = 1):
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x0A], [0x59,0x0A,0x09], 0, iStep, False, 'UDS', 'noClearFault')
          respstr = binascii.b2a_hex(bytearray(uds_resp),' ')
          with allure.step(f"Step{iStep} check failure status:{0}".format(respstr)):
               with assume: assert uds_resp[0:3] == [0x59,0x0A,0x09]
               for i in range(len(Set_up.DTC_list)):
                    dtcNumber = Set_up.DTC_list[i][0]
                    iStartByte = 3 + i * 4
                    with assume: 
                         if dtcNumber in current_failure:
                              dtcNumber = dtcNumber + [0x09]
                         elif dtcNumber in historical_failure:
                              dtcNumber = dtcNumber + [0x08]
                         else:
                              dtcNumber = dtcNumber + [0x00]

                         assert uds_resp[iStartByte:(4+iStartByte)] == dtcNumber
                    if uds_resp[iStartByte:(4+iStartByte)] != dtcNumber:
                         actualRespStr = binascii.b2a_hex(bytearray(uds_resp[iStartByte:(4+iStartByte)]),' ')
                         corrRespStr = binascii.b2a_hex(bytearray(dtcNumber),' ')
                         logging.error(f'{actualRespStr} != {corrRespStr}')
          iStep += 1

          return iStep


     
     #物理寻址，默认模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with physical addressing")
     def test_ReportSupportedDTC_Default2_Phy(self,action,Driver):
          time.sleep(1.5)
          with allure.step("Step1:Request 0x10 0x01"):
               uds_rep,size = Driver['UDS'].req_and_res_can([0x10,0x01],2)
          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step1 response{0}:".format(respstr)):
               with assume: assert uds_rep[0:6] == [0x50,0x01,0x00,0x32,0x01,0xF4]

          with allure.step("Step2:Request 0x14 0xFF 0xFF 0xFF"):
               uds_rep,size = Driver['UDS'].req_and_res_can([0x14,0xFF,0xFF,0xFF],4)
          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step2 Response:{0}".format(respstr)):
               with assume: assert uds_rep[0] == 0x54
          
          time.sleep(2)
          
          with allure.step("Step3:Request 0x19 0x0A"):
               uds_rep,size = Driver['UDS'].req_and_res_can([0x19,0x0A],2)

          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step4 Response:{0}".format(respstr)):
               with assume: assert uds_rep[0:3] == [0x59,0x0A,0x09]

               Totle_DTC_List = list(Set_up.DTC_list2.values())
               for real_reponse in np.array(uds_rep[3:]).reshape(-1,4):
                    current_DTC = real_reponse[0:3].tolist()
                    if (current_DTC in Totle_DTC_List):
                         Totle_DTC_List.remove(current_DTC)
                         logging.info('DTC number had found OK,The DTC is:'+ str(binascii.b2a_hex(bytearray(current_DTC),' ')))
                         with assume: assert True== True
                    else:
                         logging.info('DTC number had not found,The DTC is : '+ str(binascii.b2a_hex(bytearray(current_DTC),' ')))
                         with assume: assert True== False
               if len(Totle_DTC_List)>0:
                    for a in Totle_DTC_List:
                         logging.info('DTC Number ------'+ str(binascii.b2a_hex(bytearray(a),' '))  +'not include')
                    with assume: assert True == False
               else:
                    logging.info('All DTC number had been match')
                    with assume: assert True== True



class Test_ReportSupportedDTC_Fun(object):

     #物理寻址，默认模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with functional addressing")
     def test_ReportSupportedDTC_Default_Fun(self,action,Driver):
          iStep = 1
          iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
          time.sleep(1)
          self.testReportSupportedDTC(Driver,1)
          
     #物理寻址，扩展模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in extended session with functional addressing")
     def test_ReportSupportedDTC_Extended_Fun(self,action,Driver):
          self.testReportSupportedDTC(Driver,3)





     def testReportSupportedDTC(self, Driver,session):
          time.sleep(1)
          current_failure  = [[0x00,0x00,0x00]]
          iStep = 1
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], session, iStep, False, 'UDSFun', 'ClearFault')
          iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)

          # 获取存在的当前故障
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], 0, iStep, False, 'UDSFun', 'noClearFault')
          for i in range(3,size,4):
               current_failure.append(uds_resp[i:i+3])
          historical_failure=[[0x00,0x00,0x00]]

          # 检查当前故障状态
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 设置电压为17v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 17, 1.5, iStep)
          current_failure.append([0xAC,0xCE,0x17])   #当前故障list
          historical_failure=[[0x00,0x00,0x00]]   #历史故障list
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 设置电压为8v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 8, 1.5, iStep)
          current_failure.append([0xAC,0xCF,0x16])
          current_failure.remove([0xAC,0xCE,0x17])
          historical_failure=[[0xAC,0xCE,0x17]]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)
          
          # 设置电压为12v 检查当前故障状态
          iStep = Driver['CAN'].SetVolt(Driver, 12, 1.5, iStep)
          current_failure.remove([0xAC,0xCF,0x16])
          historical_failure=[[0xAC,0xCF,0x16],[0xAC,0xCE,0x17]]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)
          time.sleep(1)
          # 重启产品后，检查故障状态
          iStep = Driver['CAN'].restartMRR_Power(Driver,iStep)
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x3E,0x00], [0x7E,0x00], session, iStep, False, 'UDSFun', 'noClearFault')
          historical_failure=[0x00,0x00,0x00]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)

          # 清除故障后，检查故障状态
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x14,0xFF,0xFF,0xFF], [0x54], 0, iStep, False, 'UDSFun', 'noClearFault')
          time.sleep(2)
          historical_failure=[0x00,0x00,0x00]
          iStep = self.checkFailureStatus(Driver,uds_resp,current_failure,historical_failure,iStep)



     def checkFailureStatus(self,Driver,uds_resp,current_failure,historical_failure,iStep = 1):
          iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x0A], [0x59,0x0A,0x09], 0, iStep, False, 'UDSFun', 'noClearFault')
          respstr = binascii.b2a_hex(bytearray(uds_resp),' ')
          with allure.step(f"Step{iStep} check failure status:{0}".format(respstr)):
               with assume: assert uds_resp[0:3] == [0x59,0x0A,0x09]
               for i in range(len(Set_up.DTC_list)):
                    dtcNumber = Set_up.DTC_list[i][0]
                    iStartByte = 3 + i * 4
                    with assume: 
                         if dtcNumber in current_failure:
                              dtcNumber = dtcNumber + [0x09]
                         elif dtcNumber in historical_failure:
                              dtcNumber = dtcNumber + [0x08]
                         else:
                              dtcNumber = dtcNumber + [0x00]

                         assert uds_resp[iStartByte:(4+iStartByte)] == dtcNumber
                    if uds_resp[iStartByte:(4+iStartByte)] != dtcNumber:
                         actualRespStr = binascii.b2a_hex(bytearray(uds_resp[iStartByte:(4+iStartByte)]),' ')
                         corrRespStr = binascii.b2a_hex(bytearray(dtcNumber),' ')
                         logging.error(f'{actualRespStr} != {corrRespStr}')
          iStep += 1

          return iStep


     
     #物理寻址，默认模式，读取支持的DTC
     @allure.severity('normal')
     @allure.title("Test ReportSupportedDTC by SID 0x19 in default session with functional addressing")
     def test_ReportSupportedDTC_Default2_Fun(self,action,Driver):
          time.sleep(1.5)
          with allure.step("Step1:Request 0x10 0x01"):
               uds_rep,size = Driver['UDSFun'].req_and_res_can([0x10,0x01],2)
          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step1 response{0}:".format(respstr)):
               with assume: assert uds_rep[0:6] == [0x50,0x01,0x00,0x32,0x01,0xF4]

          with allure.step("Step2:Request 0x14 0xFF 0xFF 0xFF"):
               uds_rep,size = Driver['UDSFun'].req_and_res_can([0x14,0xFF,0xFF,0xFF],4)
          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step2 Response:{0}".format(respstr)):
               with assume: assert uds_rep[0] == 0x54
          
          time.sleep(2)
          
          with allure.step("Step3:Request 0x19 0x0A"):
               uds_rep,size = Driver['UDSFun'].req_and_res_can([0x19,0x0A],2)

          respstr = binascii.b2a_hex(bytearray(uds_rep),' ')
          with allure.step("Step4 Response:{0}".format(respstr)):
               with assume: assert uds_rep[0:3] == [0x59,0x0A,0x09]

               Totle_DTC_List = list(Set_up.DTC_list2.values())
               for real_reponse in np.array(uds_rep[3:]).reshape(-1,4):
                    current_DTC = real_reponse[0:3].tolist()
                    if (current_DTC in Totle_DTC_List):
                         Totle_DTC_List.remove(current_DTC)
                         logging.info('DTC number had found OK,The DTC is:'+ str(binascii.b2a_hex(bytearray(current_DTC),' ')))
                         with assume: assert True== True
                    else:
                         logging.info('DTC number had not found,The DTC is : '+ str(binascii.b2a_hex(bytearray(current_DTC),' ')))
                         with assume: assert True== False
               if len(Totle_DTC_List)>0:
                    for a in Totle_DTC_List:
                         logging.info('DTC Number ------'+ str(binascii.b2a_hex(bytearray(a),' '))  +'not include')
                    with assume: assert True == False
               else:
                    logging.info('All DTC number had been match')
                    with assume: assert True== True
